import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import math

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 1. 定义原始图形（三角形）
original_vertices = np.array([[2, 1], [5, 2], [3, 4]])

# 定义任意直线 Ax + By + C = 0
A, B, C = 1, -2, 3  # 直线 x - 2y + 3 = 0

# 计算直线上的两个点用于绘图
if B != 0:
    x_line = np.array([-1, 6])
    y_line = (-A * x_line - C) / B
else:  # 处理垂直情况
    x_line = np.array([-C/A, -C/A])
    y_line = np.array([-1, 6])

# 绘制初始状态
def plot_scene(vertices, line_points, title, step_num):
    fig, ax = plt.subplots(figsize=(8, 8))
    ax.set_aspect('equal')
    
    # 绘制图形
    polygon = Polygon(vertices, closed=True, fill=True, 
                     alpha=0.3, color='blue', label='图形')
    ax.add_patch(polygon)
    
    # 绘制顶点
    ax.scatter(vertices[:, 0], vertices[:, 1], color='blue', s=50)
    
    # 绘制直线
    ax.plot(line_points[0], line_points[1], 'r-', linewidth=2, 
            label=f'直线: {A}x+{B}y+{C}=0')
    
    # 设置坐标轴
    ax.set_xlim(-4, 10)
    ax.set_ylim(-4, 10)
    ax.grid(True, linestyle='--', alpha=0.7)
    ax.axhline(y=0, color='k', linestyle='-', alpha=0.3)
    ax.axvline(x=0, color='k', linestyle='-', alpha=0.3)
    ax.set_title(f'步骤 {step_num}: {title}', fontsize=14)
    ax.legend()
    plt.show()

# 绘制初始图形和直线
plot_scene(original_vertices, [x_line, y_line], "原始图形和直线", 0)


# 计算平移量：找到直线上一点，将其平移到原点
if A != 0:
    # 取直线与x轴交点
    translate_x = -C / A
    translate_y = 0
else:
    # 取直线与y轴交点
    translate_x = 0
    translate_y = -C / B
# 平移矩阵
translation_matrix = np.array([[1, 0, -translate_x],
                              [0, 1, -translate_y],
                              [0, 0, 1]])

# 对图形顶点进行平移（齐次坐标）
def apply_transform(vertices, transform_matrix):
    homogeneous_coords = np.column_stack([vertices, np.ones(len(vertices))])
    transformed = homogeneous_coords @ transform_matrix.T
    return transformed[:, :2]

# 应用平移变换
vertices_step1 = apply_transform(original_vertices, translation_matrix)

# 更新直线方程（常数项C变为0）
C_step1 = 0

# 计算新直线上的点
if B != 0:
    y_line_step1 = (-A * x_line - C_step1) / B
else:
    y_line_step1 = y_line

# 绘制步骤1结果
plot_scene(vertices_step1, [x_line, y_line_step1], 
           "平移直线过原点", 1)


# 计算直线与X轴的夹角
line_angle = math.atan2(A, -B)  # 法向量(A,B)与X轴夹角

# 旋转矩阵（将直线旋转到X轴）
rotation_matrix = np.array([[math.cos(-line_angle), -math.sin(-line_angle), 0],
                           [math.sin(-line_angle), math.cos(-line_angle), 0],
                           [0, 0, 1]])

# 应用旋转变换
vertices_step2 = apply_transform(vertices_step1, rotation_matrix)

# 计算旋转后的直线（现在应与X轴重合）
# 直线方程变为：x = 0（在旋转后的坐标系中）
x_line_step2 = np.array([-1, 6])
y_line_step2 = np.array([0, 0])

# 绘制步骤2结果
plot_scene(vertices_step2, [x_line_step2, y_line_step2], 
           "旋转直线至与X轴重合", 2)


# 关于X轴对称的变换矩阵
reflection_matrix = np.array([[1, 0, 0],
                             [0, -1, 0],
                             [0, 0, 1]])

# 应用对称变换
vertices_step3 = apply_transform(vertices_step2, reflection_matrix)

# 直线保持不变（仍在X轴上）
x_line_step3 = x_line_step2
y_line_step3 = y_line_step2

# 绘制步骤3结果
plot_scene(vertices_step3, [x_line_step3, y_line_step3], "关于X轴对称", 3)


# 逆旋转矩阵（转回原方向）
inverse_rotation_matrix = np.array([[math.cos(line_angle), -math.sin(line_angle), 0],
                                   [math.sin(line_angle), math.cos(line_angle), 0],
                                   [0, 0, 1]])

inverse_rotation_matrix = np.array([
    [math.cos(line_angle), -math.sin(line_angle), 0],
    [math.sin(line_angle), math.cos(line_angle), 0],
    [0, 0, 1]
])

# 应用逆旋转变换
vertices_step4 = apply_transform(vertices_step3, inverse_rotation_matrix)

# 计算逆旋转后的直线
if B != 0:
    y_line_step4 = (-A * x_line - C_step1) / B
else:
    y_line_step4 = y_line

# 绘制步骤4结果
plot_scene(vertices_step4, [x_line, y_line_step4], 
           "逆旋转直线回原位", 4)

# 逆平移矩阵
print(translate_x, translate_y)
inverse_translation_matrix = np.array([[1, 0, translate_x],
                                      [0, 1, translate_y],
                                      [0, 0, 1]])

# 应用逆平移变换

vertices_step5 = apply_transform(vertices_step4, inverse_translation_matrix)
print("vertices_step1", vertices_step1)
print("vertices_step2", vertices_step2)
print("vertices_step3", vertices_step3)
print("vertices_step4", vertices_step4)
print("vertices_step5", vertices_step5)

# 计算最终直线（回到原始位置）
if B != 0:
    y_line_final = (-A * x_line - C) / B
else:
    y_line_final = y_line

# 绘制最终结果
plot_scene(vertices_step5, [x_line, y_line_final], 
           "逆平移直线回原位 - 最终对称图形", 5)
